require 'csv'

module Shamela
  class Book
    def initialize(book_filename)
      @book_filename = book_filename
      table_names = `mdb-tables '#{@book_filename}'`.split
      @sections_table = table_names.find{|t| t.start_with?('t')}
      @documents_table = table_names.find{|t| t.start_with?('b')}
      @collection_table = table_names.find{|t| t == "Main"}
    end
    
    def read_main_info
      main_csv = `mdb-export '#{@book_filename}' #{@collection_table}`
      main_csv = ::Shamela::Common.decode(main_csv)
      header, data = main_csv.split(/[\r\n]/, 2)
      #BkId,Bk,Betaka,Inf,Auth,AuthInf,TafseerNam,IslamShort
      header = header.split(/\s*,\s*/)
      # parse csv data
      csv = CSV::Reader.parse(data)
      csv.each do |csv_row|
        @title = csv_row[1]
        @description = csv_row[2]
      end
    end
    
    def read_sections
      sections_csv = `mdb-export '#{@book_filename}' #{@sections_table}`
      sections_csv = ::Shamela::Common.decode(sections_csv)
      header, data = sections_csv.split(/[\r\n]/, 2)
      header = header.split(/\s*,\s*/)
      # parse csv data
      csv = CSV::Reader.parse(data)
      all_sections = []
      last_sections = []
      csv.each do |csv_row|
        section = ::Shamela::Section.new(csv_row, header)
        all_sections << section
        last_sections[section.lvl.to_i] = section
        if last_sections[section.lvl.to_i-1]
          parent = last_sections[section.lvl.to_i-1]
          parent.subsections << section
          section.parent = parent
        end
      end
      return all_sections
    end
    
    def read_documents(all_sections)
      documents_csv = `mdb-export '#{@book_filename}' #{@documents_table}`
      documents_csv = ::Shamela::Common.decode(documents_csv)
      header, data = documents_csv.split(/[\r\n]/, 2)
      header = header.split(/\s*,\s*/)
      
      id_to_section = {}
      all_sections.each do |section|
        id_to_section[section.id] = section
      end
      # parse csv data
      all_documents = []
      last_section = all_sections[0]
      document_position = 0
      csv = CSV::Reader.parse(data)
      csv.each do |csv_row|
        document = ::Shamela::Document.new(csv_row, header)
        section = id_to_section[document.id]
        if section
          section.description = document.nass
          last_section = section
          document_position = 0
        else
          # sanity check
          raise "Error with document #{document}" if document.id.to_i < last_section.id.to_i
          document.section = last_section
          last_section.documents << document.section
          all_documents << document
        end
      end
      return all_documents
    end
    
    def save_to_db
      read_main_info
      collection = Collection.new(:title=>@title,:description=>@description)
      puts "Created collection: #{collection.title}"
      all_sections = read_sections
      puts "Read #{all_sections.size} sections"
      all_documents = read_documents(all_sections)
      puts "Read #{all_documents.size} documents"
      i = 0
      while i < all_sections.size do
        section = all_sections[i]
        if section.documents.any? || section.subsections.any? || section.parent.nil?
          i+=1
          next
        end
        # Convert this section to a document
        parent = section.parent
        document = Document.new
        document.id = section.id
        document.nass = section.description
        document.section = parent
        document.type = "Hadith"
        parent.documents << document
        parent.subsections.delete(section)
        deleted_section = all_sections.delete_at(i)
        all_documents << document
      end
      puts "Done converting..."
      puts "Sections are now: #{all_sections.size}"
      puts "Documents are now: #{all_documents.size}"
      section_to_db = {}
      all_sections.each do |section|
        db_section = section.to_db
        db_section.parent = section_to_db[section.parent]
        collection.sections << db_section
        section_to_db[section] = db_section
      end
      puts "Saved sections"
      all_documents.sort{|a,b| a.id<=>b.id}.each do |document|
        db_document = document.to_db
        section_to_db[document.section].documents << db_document
      end
      puts "Saved documents"
      collection.save
      puts "Committed to DB"
      # Commit indexed documents
#      ::Document.solr_optimize
#      ::Document.solr_commit
      puts "Index committed"
    end
  end
end
